
#include <mex.h>
#include <string.h>

#include "shm_array.h"

static void usage_error (){
	mexErrMsgTxt("X = read_shmmat('key string');\n");
}

void
mexFunction (int nl, mxArray *pl[], int nr, mxArray const *pr[])
{
	int i;
	char *key;
	struct shm_array *shm;

	if (nr != 1 || nl != 1) usage_error();

	if (nr == 1){
		if (!mxIsChar(pr[0])) usage_error();
		key = mxArrayToString (pr[0]);
	}

	if (get_shm_array (key, &shm)){
		mexErrMsgTxt("ERROR");
	}

	mxClassID IDs[n_shm_array_types] = {
		mxCHAR_CLASS,
		mxINT32_CLASS,
		mxINT64_CLASS, 
		mxSINGLE_CLASS,
		mxDOUBLE_CLASS,
		mxSINGLE_CLASS,
		mxDOUBLE_CLASS
	};

	mxComplexity CPLX[n_shm_array_types] = {
		mxREAL,
		mxREAL,
		mxREAL,
		mxREAL,
		mxREAL,
		mxCOMPLEX,
		mxCOMPLEX
	};

	mwSize *dims = (mwSize *) malloc (sizeof(mwSize)*shm->ndims);
	for (i = 0; i < shm->ndims; ++i)
		dims[i] = shm->dims[i];

	pl[0] = mxCreateNumericArray (shm->ndims, dims,
	                              IDs[shm->type], CPLX[shm->type]);

	free (dims);

	if (!mxIsComplex(pl[0])){
		int n = shm_type_sizes[shm->type];
		for (i = 0; i < shm->ndims; ++i)
			n *= shm->dims[i];

		memcpy (mxGetData (pl[0]), shm->data.s, n);
	}
	else
	{
		int n = 1;
		for (i = 0; i < shm->ndims; ++i)
			n *= shm->dims[i];

		if (shm->type == shm_array_cplxf){
			for (i = 0; i < n; ++i){
				((float*) mxGetData(pl[0]))[i] = shm->data.c[i].real;
				((float*) mxGetImagData(pl[0]))[i] = shm->data.c[i].imag;
			}
		}else{
			for (i = 0; i < n; ++i){
				mxGetPr(pl[0])[i] = shm->data.z[i].real;
				mxGetPi(pl[0])[i] = shm->data.z[i].imag;
			}
		}
	}

	put_shm_array (key, shm);
	mxFree (key);
}
